home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / presto / presto10.lha / src / spinlock.h < prev    next >
C/C++ Source or Header  |  1991-12-11  |  4KB  |  206 lines

  1. #ifndef __presto__spinlock_h__
  2. #define __presto__spinlock_h__
  3.  
  4. //
  5. // Spinlocks should be used when the caller expects to need to touch
  6. // a piece of data for only a very short time.  Interference on that
  7. // data will cause the later thread to spin (his processor does not
  8. // become available!)
  9. //
  10. //    USE WITH CAUTION
  11. //
  12. // Modification History:
  13. //
  14. // 28-Dec-1989  JEF
  15. // Add class HC_Spinlock (for sequent symmetry only).  This variation of
  16. // a spinlock works well when there is high contention for the lock.
  17. // After original by raj.
  18. //
  19.  
  20. //
  21. // If compiling presto kernel, or compiling with preemption 
  22. // included, then include code to make threads not preemptable
  23. // inside spinlock.  Else, omit for speed.
  24. //
  25.  
  26. //
  27. //  For better locking performance, spinlocks should be compiled inline.
  28. //
  29.  
  30. #define DO_SPINLOCK_INLINE
  31. #ifdef DO_SPINLOCK_INLINE
  32. #define SPINLOCK_INLINE     inline
  33. #else
  34. #define SPINLOCK_INLINE
  35. #endif
  36.  
  37. #ifdef sequent
  38. #include "parallel.h"
  39. extern "C" {
  40. void  S_INIT_LOCK (slock_t *);
  41. void  S_LOCK      (slock_t *);
  42. void  S_UNLOCK    (slock_t *);
  43. int   S_CLOCK     (slock_t *);
  44.  
  45. void  HC_S_LOCK(hc_slock_t *);
  46. void  HC_S_UNLOCK(hc_slock_t *);
  47. int   HC_S_INIT_LOCK(hc_slock_t *); // should probably be void
  48. int   HC_S_CLOCK(hc_slock_t *);
  49. int   HC_S_IS_LOCKED(hc_slock_t *);
  50. }
  51. #endif /* sequent */
  52.  
  53. #ifdef sun
  54. #include "parallel.h"
  55. #define S_LOCK s_lock
  56. #endif /* sun */
  57.  
  58. #ifdef vax
  59. typedef    int slock_t;
  60. #define L_UNLOCKED 0
  61. #define S_LOCK s_lock
  62. #define S_UNLOCK s_unlock
  63. #define S_INIT_LOCK s_init_lock
  64. #define S_CLOCK s_clock
  65. #endif /* vax */
  66.  
  67. #ifdef mips
  68. typedef    int slock_t;
  69. #define L_UNLOCKED 0
  70. #define S_LOCK s_lock
  71. #define S_UNLOCK s_unlock
  72. #define S_INIT_LOCK s_init_lock
  73. #define S_CLOCK s_clock
  74. #endif /* mips */
  75.  
  76. extern void s_init_lock (slock_t*);
  77. extern void s_lock      (slock_t*);
  78. extern void s_unlock    (slock_t*);
  79. extern int  s_clock     (slock_t*);
  80.  
  81. class Thread;
  82.  
  83. class Spinlock    : public Object  {    
  84.     slock_t        sl_lock;
  85. #ifdef PROFILE
  86.     int    sl_q;
  87. #endif
  88. public:
  89.     Spinlock(char *name = 0) 
  90.         {
  91.         S_INIT_LOCK(&sl_lock); 
  92.         name = name; // satisfy cfront and/or ANSI C
  93. #ifdef PROFILE
  94.         sl_q = SLInit(name);
  95. #endif
  96.         }
  97.     SPINLOCK_INLINE ~Spinlock();
  98.  
  99.     //
  100.     // Acquire lock, spinning until it is free.
  101.     //
  102.     SPINLOCK_INLINE void lock();
  103.  
  104.     //
  105.     // Acquire lock and return true iff lock is free, else return
  106.     // false immediately without spinning.
  107.     //
  108.     int trylock()
  109.         { return  S_CLOCK(&sl_lock); }
  110.  
  111.     //
  112.     // Old name for trylock().
  113.     //
  114.     int checklock()
  115.         { return  trylock(); }
  116.  
  117.     //
  118.     // Return true iff locked, else false.
  119.     //
  120.     int testlock()
  121.         { return  sl_lock; }
  122.  
  123.     //
  124.     // Release lock.
  125.     //
  126.     SPINLOCK_INLINE void unlock();
  127.     virtual void print(ostream& = cout);
  128. };
  129.      
  130.  
  131.  
  132. //
  133. //  High-contention spinlocks are only implemented on sequent symmetry.
  134. //
  135.  
  136. #ifdef sequent
  137. #ifdef i386
  138.  
  139. class Thread;
  140.  
  141. class HC_Spinlock : public Object  {    
  142.     hc_slock_t    sl_lock;
  143. #ifdef PROFILE
  144.     int    sl_q;
  145. #endif
  146. public:
  147.     HC_Spinlock(char *name = 0)
  148.         {
  149.         HC_S_INIT_LOCK(&sl_lock); 
  150.         name = name; // satisfy cfront and/or ANSI C
  151. #ifdef PROFILE
  152.         sl_q = SLInit(name);
  153. #endif
  154.         }
  155.  
  156.     ~HC_Spinlock()
  157.     {
  158.         //
  159.         // We should abort if the lock is not free. (?) XXX
  160.         // For now just unlock it for backward compatibility.
  161.         //
  162.         if (testlock())
  163.             unlock();
  164. #ifdef PROFILE
  165.     SLDispose(sl_q);
  166. #endif
  167.     }
  168.  
  169.     //
  170.     // Acquire lock, spinning until it is free.
  171.     //
  172.     inline void lock();
  173.  
  174.     //
  175.     // Acquire lock and return true iff lock is free, else return
  176.     // false immediately without spinning.
  177.     //
  178.     int trylock()  {
  179.         cerr << "HC_Spinlock::trylock(): unimplemented\n"; 
  180.         /* XXX for now, always returns FALSE */
  181.         return (HC_S_CLOCK(&sl_lock));
  182.     }
  183.  
  184.     //
  185.     // Old name for trylock().
  186.     //
  187.     int checklock() 
  188.         { return (trylock()); }
  189.  
  190.     //
  191.     // Return true iff locked, else false.
  192.     //
  193.     int testlock()
  194.         { return  HC_S_IS_LOCKED(&sl_lock); }
  195.  
  196.     //
  197.     // Release lock.
  198.     //
  199.     inline void unlock();
  200.     virtual void print(ostream& = cout);
  201. };
  202.      
  203. #endif /* i386 */
  204. #endif /* sequent */
  205. #endif /* __presto__spinlock_h__ */
  206.